home *** CD-ROM | disk | FTP | other *** search
- /*
-
- File: testdisk.c
-
- Copyright (C) 1998-2004 Christophe GRENIER <grenier@cgsecurity.org>
-
- This software is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
-
- #include <stdarg.h>
- #include <unistd.h> /* geteuid */
- #include <string.h>
- #include <time.h>
- #include <sys/time.h>
- #include <ctype.h> /* toupper, tolower */
- #include <locale.h> /* setlocale */
- #include "types.h"
- #include "common.h"
- #include "testdisk.h"
- #include "lang.h"
- #include "intrface.h"
- #include "godmode.h"
- #include "fnctdsk.h"
- #include "version.h"
-
- static FILE* init_log(const char*filename,int argc, char**argv);
-
- static FILE *f_rapport=NULL;
- static int f_status=0;
-
- void ecrit_rapport_string(const char *string,const int max_length)
- {
- int i;
- for(i=0;(string[i]!='\0')&&(i<max_length);i++)
- ecrit_rapport("%c",string[i]);
- }
-
- int ecrit_rapport(const char *_format, ...)
- {
- int res=0;
- if(f_rapport!=NULL)
- {
- va_list ap;
- va_start(ap,_format);
- res=vfprintf(f_rapport,_format,ap);
- va_end(ap);
- if(fflush(f_rapport))
- {
- f_status=1;
- }
- }
- return res;
- }
-
- static FILE* init_log(const char*filename,int argc, char**argv)
- {
- FILE*f_file=fopen(filename,"a");
- if(f_file==NULL)
- printf(msg_LOG_ERR);
- else
- {
- int i;
- time_t my_time=time(NULL);
- fprintf(f_file,"\n\n%s",ctime(&my_time));
- fprintf(f_file,msg_CMDLINE);
- for(i=1;i<argc;i++)
- fprintf(f_file," %s", argv[i]);
- fprintf(f_file,"\n");
- }
- return f_file;
- }
-
-
- int main( int argc, char **argv )
- {
- int i;
- unsigned int x;
- int help=0, create_log=0,paranoid=0,debug=0, dump_ind=0;
- int fast_mode=0;
- int align=1;
- int do_analyse=1;
- int do_list=0;
- int test_recovery=0;
- int write_used=0;
- t_list_disk *list_disk=NULL;
- t_list_disk *element_disk;
- #ifdef TESTING
- srand(1);
- #endif
- for(i=1;i<argc;i++)
- {
- for (x=0; x < strlen( argv[i] ); x++)
- argv[i][x] = tolower( argv[i][x] );
- if((strcmp(argv[i],"/test_recovery")==0) ||(strcmp(argv[i],"-test_recovery")==0))
- {
- test_recovery=1;
- do_list=1;
- create_log=1;
- }
- else if((strcmp(argv[i],"/dump")==0) || (strcmp(argv[i],"-dump")==0))
- dump_ind=1;
- else if((strcmp(argv[i],"/log")==0) ||(strcmp(argv[i],"-log")==0))
- create_log=1;
- else if((strcmp(argv[i],"/debug")==0) || (strcmp(argv[i],"-debug")==0))
- {
- debug++;
- create_log=1;
- }
- else if((strcmp(argv[i],"/list")==0) || (strcmp(argv[i],"-list")==0))
- do_list=1;
- else if((strcmp(argv[i],"/help")==0) || (strcmp(argv[i],"-help")==0) || (strcmp(argv[i],"--help")==0) ||
- (strcmp(argv[i],"/h")==0) || (strcmp(argv[i],"-h")==0))
- help=1;
- else
- {
- list_disk=insert_new_disk(list_disk,file_test_availability(argv[i],debug));
- if(list_disk==NULL)
- {
- help=1;
- }
- }
- }
- printf(msg_Copyright);
- if(help!=0)
- {
- printf(msg_Usage);
- return 0;
- }
- if(create_log!=0)
- {
- /* const char *ext2fs_version=NULL; */
- f_rapport=init_log("testdisk.log",argc,argv);
- ecrit_rapport(msg_Copyright);
- #ifdef DJGPP
- ecrit_rapport("Dos version");
- #elif defined(BSD)
- ecrit_rapport("BSD version");
- #elif defined(LINUX)
- ecrit_rapport("Linux version");
- #else
- ecrit_rapport("Undefined OS");
- #endif
- #ifdef COMPILE_BY
- #ifdef COMPILE_HOST
- #ifdef COMPILE_TIME
- ecrit_rapport(" (%s@%s, %s)",COMPILE_BY,COMPILE_HOST,COMPILE_TIME);
- #endif
- #endif
- #endif
- ecrit_rapport("\n");
- /* ext2fs_get_library_version(ext2fs_version,NULL); */
- /* ecrit_rapport("%s\n\n",ext2fs_version); */
- #ifdef DEBUG
- ecrit_rapport("Key down: 0x%x\n", KEY_DOWN);
- ecrit_rapport("Key up: 0x%x\n", KEY_UP);
- ecrit_rapport("Key left: 0x%x\n", KEY_LEFT);
- ecrit_rapport("Key right: 0x%x\n", KEY_RIGHT);
- ecrit_rapport("Key page down: 0x%x\n", KEY_NPAGE);
- ecrit_rapport("Key page up: 0x%x\n", KEY_PPAGE);
- ecrit_rapport("Key enter: 0x%x\n", KEY_ENTER);
- #endif
- }
- printf("Please wait...\n");
- {
- const char *locale;
- locale = setlocale (LC_ALL, "");
- if (locale==NULL) {
- locale = setlocale (LC_ALL, NULL);
- ecrit_rapport("Failed to set locale, using default '%s'.\n", locale);
- } else {
- ecrit_rapport("Using locale '%s'.\n", locale);
- }
- }
- list_disk=hd_parse(list_disk,debug);
- if(list_disk==NULL)
- {
- printf("No harddisk found\n");
- #ifndef DJGPP
- if(geteuid()!=0)
- {
- printf("You need to be root to use TestDisk\n");
- ecrit_rapport("You need to be root to use TestDisk\n");
- }
- #endif
- }
- #ifdef DJGPP
- for(element_disk=list_disk;element_disk;element_disk=element_disk->next)
- {
- printf("%s",element_disk->disk->description(element_disk->disk));
- }
- #endif
- hd_parse_bis(list_disk,0);
- /* save disk parameters to rapport */
- ecrit_rapport("Hard disk list\n");
- for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
- {
- printf("%s",element_disk->disk->description(element_disk->disk));
- ecrit_rapport("%s",element_disk->disk->description(element_disk->disk));
- }
- printf("\n");
- ecrit_rapport("\n");
-
- if(do_list!=0)
- {
- for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
- {
- interface_list(element_disk->disk,debug,test_recovery);
- if(test_recovery!=0)
- {
- t_list_part *list_part=search_part(element_disk->disk,paranoid,debug,0,fast_mode,0);
- if(debug!=0)
- {
- t_list_part *element;
- ecrit_rapport("search_part() results\n");
- for(element=list_part;element!=NULL;element=element->next)
- aff_part_rapport(element_disk->disk,element->part);
- }
- delete_list_part(list_part);
- }
- }
- }
- else
- {
- if(do_curses_testdisk(debug,paranoid,dump_ind,fast_mode,align,do_analyse,list_disk))
- {
- printf("TestDisk need 25 lines to work.\nPlease enlarge the terminal and restart TestDisk.\n");
- }
- }
- for(element_disk=list_disk;element_disk!=NULL;)
- {
- t_list_disk *element_disk_next=element_disk->next;
- write_used|=element_disk->disk->write_used;
- if(element_disk->disk->clean!=NULL)
- element_disk->disk->clean(element_disk->disk);
- FREE(element_disk->disk);
- element_disk=element_disk_next;
- }
- if(f_rapport!=NULL)
- {
- ecrit_rapport("TestDisk exited normally.\n");
- if(fclose(f_rapport))
- {
- f_status=1;
- }
- }
- if(f_status!=0)
- {
- printf("TestDisk: Log file corrupted!\n");
- }
- else
- {
- printf("TestDisk exited normally.\n");
- }
- if(write_used!=0)
- {
- printf("You have to reboot for the change to take effect.\n");
- }
- return 0;
- }
-
- #ifdef DEBUG
-
- #include "fat.h"
- static int load_dump(const char*filename, unsigned char * buffer, const int size);
-
-
- int do_test()
- {
- FILE *file_in;
- unsigned char buffer[10*SECTOR_SIZE];
- unsigned int taille;
- t_param_disk *disk_car=(t_param_disk)MALLOC(sizeof(*disk_car));
- t_diskext *partition=partition_new(0);
- initscr();
- noecho();
- keypad(stdscr, TRUE); /* Need it to get arrow key */
- #ifndef DJGPP
- nonl(); /*don't use for Dos version but enter will work with it... dilema */
- #endif
- crmode();
- /* intrflush(stdscr, FALSE); */
- cbreak();
-
- file_in=fopen("BOOT_BIN.txt","rb");
- if(!file_in)
- return 1;
- taille=fread(buffer,1,10*SECTOR_SIZE,file_in);
- fclose(file_in);
- if(memcmp(buffer,"0000 ",5)==0)
- {
- int pos_file;
- int pos_buffer2=0;
- unsigned char buffer2[3*SECTOR_SIZE];
- for(pos_file=5;pos_file<taille;)
- {
- char string[3];
- if(buffer[pos_file]==' ')
- pos_file++;
- string[0]=buffer[pos_file];
- string[1]=buffer[pos_file+1];
- string[2]=0;
- printf("%02X",strtol(string,NULL,16));
- buffer2[pos_buffer2++]=strtol(string,NULL,16);
- if(pos_buffer2%16==0)
- {
- pos_file+=18;
- if(buffer[pos_file]==0xA || buffer[pos_file]==0xD)
- pos_file++;
- if(buffer[pos_file]==0xA || buffer[pos_file]==0xD)
- pos_file++;
- pos_file+=9;
- }
- else
- pos_file+=2;
- }
- /* buffer2_size=pos_buffer2-1; */
- memcpy(buffer,buffer2,3*SECTOR_SIZE);
- }
- printf("do_test\n");
- aff_buffer(BUFFER_RESET,"Q");
- dump_fat_info(buffer,P_16FAT);
- test_FAT(disk_car,(struct fat_boot_sector *)&buffer, partition,1, 1);
- aff_buffer(BUFFER_DISPLAY,"Q",stdscr);
- return 0;
- }
-
- static int load_dump(const char*filename, unsigned char * buffer, const int size)
- {
- FILE *f_in;
- unsigned char ligne[200];
- int position=0;
- int lu;
- int etat=0;
- unsigned char val=0;
- int position_ligne=0;
- memset(buffer,0,size);
- if((f_in=fopen(filename,"r"))==NULL)
- return 1;
- /* ecrit_rapport("load_dump %s ok\n",filename); */
- while(!feof(f_in) && ((lu=fread(ligne,1,sizeof(ligne)-1,f_in))>0))
- {
- int i;
- ligne[sizeof(ligne)-1]=0;
- /* ecrit_rapport("ligne=%s,lu=%d\n",ligne,lu); */
- for(i=0;i<lu;i++)
- {
- unsigned char car=ligne[i];
- /* ecrit_rapport("etat=%d, car=%02X(%c), val=%02X, position_ligne=%d, position=%04X\n",etat,car,car,val,position_ligne,position); */
- switch(etat)
- {
- case 0:
- if(car==':')
- etat=1;
- break;
- case 1:
- if(car!=' ')
- {
- if(car>='0' && car<='9')
- val=(val<<4)|(car-'0');
- else
- val=(val<<4)|(car-'A'+10);
- etat=2;
- }
- break;
- case 2:
- if(car>='0' && car<='9')
- val=(val<<4)|(car-'0');
- else
- val=(val<<4)|(car-'A'+10);
- buffer[position]=val;
- position++;
- position_ligne++;
- if(position_ligne<0x10)
- etat=1;
- else
- etat=3;
- break;
- case 3:
- if(car=='\n')
- {
- etat=0;
- position_ligne=0;
- }
- break;
- } /* end switch */
- } /* end for lu */
- } /* end while */
- fclose(f_in);
- return 0;
- }
- #endif
-